a tool for shared writing and social publishing
1import { AtUri } from "@atproto/api";
2import { z } from "zod";
3import { makeRoute } from "../lib";
4import type { Env } from "./route";
5import { getPublicationURL } from "app/lish/createPub/getPublicationURL";
6
7export type SearchPublicationDocumentsReturnType = Awaited<
8 ReturnType<(typeof search_publication_documents)["handler"]>
9>;
10
11export const search_publication_documents = makeRoute({
12 route: "search_publication_documents",
13 input: z.object({
14 publication_uri: z.string(),
15 query: z.string(),
16 limit: z.number().optional().default(10),
17 }),
18 handler: async (
19 { publication_uri, query, limit },
20 { supabase }: Pick<Env, "supabase">,
21 ) => {
22 // Get documents in the publication, filtering by title using JSON operator
23 // Also join with publications to get the record for URL construction
24 const { data: documents, error } = await supabase
25 .from("documents_in_publications")
26 .select(
27 "document, documents!inner(uri, data), publications!inner(uri, record)",
28 )
29 .eq("publication", publication_uri)
30 .ilike("documents.data->>title", `%${query}%`)
31 .limit(limit);
32
33 if (error) {
34 throw new Error(
35 `Failed to search publication documents: ${error.message}`,
36 );
37 }
38
39 const result = documents.map((d) => {
40 const docUri = new AtUri(d.documents.uri);
41 const pubUrl = getPublicationURL(d.publications);
42
43 return {
44 uri: d.documents.uri,
45 title: (d.documents.data as { title?: string })?.title || "Untitled",
46 url: `${pubUrl}/${docUri.rkey}`,
47 };
48 });
49
50 return { result: { documents: result } };
51 },
52});